package com.rickpan.socketio;

import com.corundumstudio.socketio.SocketIOClient;
import com.corundumstudio.socketio.SocketIOServer;
import com.corundumstudio.socketio.annotation.OnConnect;
import com.corundumstudio.socketio.annotation.OnDisconnect;
import com.corundumstudio.socketio.annotation.OnEvent;
import com.rickpan.entity.TransferRecord;
import com.rickpan.entity.UserOnlineStatus;
import com.rickpan.entity.FriendRequest;
import com.rickpan.entity.FriendRelationship;
import com.rickpan.service.TransferRecordService;
import com.rickpan.service.UserOnlineService;
import com.rickpan.service.ContactService;
import com.rickpan.repository.UserOnlineStatusRepository;
import com.rickpan.repository.FriendRelationshipRepository;
import com.rickpan.event.TransferEvent;
import com.rickpan.dto.response.TransferRecordDTO;
import com.rickpan.dto.contacts.FriendRequestResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * 传输事件处理器
 * 处理Socket.IO客户端连接和传输相关事件
 */
@Component
public class TransferEventHandler {

    private static final Logger logger = LoggerFactory.getLogger(TransferEventHandler.class);

    @Autowired
    private SocketIOServer socketIOServer;

    @Autowired
    private TransferRecordService transferRecordService;

    @Autowired
    private UserOnlineService userOnlineService;

    @Autowired
    private ContactService contactService;

    @Autowired
    private UserOnlineStatusRepository userOnlineStatusRepository;

    @Autowired
    private FriendRelationshipRepository friendRelationshipRepository;

    // 存储用户ID与Socket客户端的映射关系
    private final Map<Long, SocketIOClient> userClientMap = new ConcurrentHashMap<>();
    private final Map<String, Long> sessionUserMap = new ConcurrentHashMap<>();

    /**
     * 通用事件监听器 - 用于调试
     */
    @OnEvent("*")
    public void onAnyEvent(SocketIOClient client, String eventName, Object... data) {
        String sessionId = client.getSessionId().toString();
        Long userId = sessionUserMap.get(sessionId);
        logger.info("🔍 收到Socket事件: eventName={}, userId={}, sessionId={}, data={}",
            eventName, userId, sessionId, data);
    }

    /**
     * 客户端连接事件
     */
    @OnConnect
    public void onConnect(SocketIOClient client) {
        String sessionId = client.getSessionId().toString();
        // logger.debug("Socket.IO客户端连接: sessionId={}", sessionId); // 开发调试用

        // 从连接参数中获取用户ID
        String userIdParam = client.getHandshakeData().getSingleUrlParam("userId");
        if (userIdParam != null) {
            try {
                Long userId = Long.parseLong(userIdParam);
                userClientMap.put(userId, client);
                sessionUserMap.put(sessionId, userId);
                
                // 只记录重要的用户连接信息
                logger.info("用户连接成功: userId={}, sessionId={}", userId, sessionId);

                // 获取客户端信息
                Map<String, Object> clientInfo = new HashMap<>();
                clientInfo.put("userAgent", client.getHandshakeData().getHttpHeaders().get("user-agent"));
                clientInfo.put("remoteAddress", client.getRemoteAddress().toString());
                clientInfo.put("sessionId", sessionId);

                // 设置用户在线状态（Redis）
                userOnlineService.userOnline(userId, sessionId, clientInfo);

                // 更新数据库在线状态
                updateUserOnlineStatusInDB(userId, sessionId, clientInfo);

                // 发送连接成功消息
                Map<String, Object> connectedData = new HashMap<>();
                connectedData.put("status", "success");
                connectedData.put("message", "连接成功");
                connectedData.put("userId", userId);
                connectedData.put("sessionId", sessionId);
                connectedData.put("onlineUserCount", userOnlineService.getOnlineUserCount());
                client.sendEvent("connected", connectedData);

                // 发送消息服务连接确认
                Map<String, Object> messageConnectedData = new HashMap<>();
                messageConnectedData.put("status", "connected");
                messageConnectedData.put("message", "消息服务连接成功");
                messageConnectedData.put("userId", userId);
                messageConnectedData.put("timestamp", System.currentTimeMillis());
                client.sendEvent("message:connected", messageConnectedData);

                // 发送当前进行中的传输记录
                sendActiveTransfers(client, userId);

                // 广播用户上线事件给其他用户
                broadcastUserStatusChange(userId, "ONLINE");

                // 通知好友用户上线
                notifyFriendsUserOnline(userId);
                
            } catch (NumberFormatException e) {
                logger.warn("⚠️ 无效的用户ID参数: {}", userIdParam);
                Map<String, Object> errorData = new HashMap<>();
                errorData.put("message", "无效的用户ID");
                client.sendEvent("error", errorData);
            }
        } else {
            logger.warn("⚠️ 客户端连接缺少用户ID参数: sessionId={}", sessionId);
            Map<String, Object> errorData = new HashMap<>();
            errorData.put("message", "缺少用户ID参数");
            client.sendEvent("error", errorData);
        }
    }

    /**
     * 客户端断开连接事件
     */
    @OnDisconnect
    public void onDisconnect(SocketIOClient client) {
        String sessionId = client.getSessionId().toString();
        Long userId = sessionUserMap.remove(sessionId);

        if (userId != null) {
            userClientMap.remove(userId);

            // 更新用户离线状态（Redis）
            userOnlineService.userOffline(userId, sessionId);

            // 检查用户是否完全离线
            boolean isStillOnline = userOnlineService.isUserOnline(userId);
            if (!isStillOnline) {
                // 更新数据库离线状态
                updateUserOfflineStatusInDB(userId);

                // 广播用户下线事件给其他用户
                broadcastUserStatusChange(userId, "OFFLINE");

                // 通知好友用户下线
                notifyFriendsUserOffline(userId);
            }

            logger.info("🔌 用户断开连接: userId={}, sessionId={}, 仍在线: {}", userId, sessionId, isStillOnline);
        } else {
            logger.info("🔌 客户端断开连接: sessionId={}", sessionId);
        }
    }

    /**
     * 获取传输历史记录事件
     */
    @OnEvent("getTransferHistory")
    public void onGetTransferHistory(SocketIOClient client, Map<String, Object> data) {
        String sessionId = client.getSessionId().toString();
        Long userId = sessionUserMap.get(sessionId);
        
        if (userId == null) {
            Map<String, Object> errorData = new HashMap<>();
            errorData.put("message", "用户未认证");
            client.sendEvent("error", errorData);
            return;
        }

        try {
            // 获取分页参数
            int page = (Integer) data.getOrDefault("page", 0);
            int size = (Integer) data.getOrDefault("size", 20);
            String filter = (String) data.getOrDefault("filter", "all");

            // 查询传输历史记录

            // 查询传输历史记录
            var historyPage = transferRecordService.getTransferHistory(userId, page, size, filter);

            // 转换为DTO
            var recordDTOs = historyPage.getContent().stream()
                    .map(TransferRecordDTO::from)
                    .toList();

            Map<String, Object> historyData = new HashMap<>();
            historyData.put("records", recordDTOs);
            historyData.put("totalElements", historyPage.getTotalElements());
            historyData.put("totalPages", historyPage.getTotalPages());
            historyData.put("currentPage", page);
            client.sendEvent("transferHistory", historyData);

            // 发送传输历史记录

        } catch (Exception e) {
            logger.error("❌ 获取传输历史记录失败: userId={}", userId, e);
            Map<String, Object> errorData = new HashMap<>();
            errorData.put("message", "获取传输历史失败");
            client.sendEvent("error", errorData);
        }
    }

    /**
     * 清除传输历史记录事件
     */
    @OnEvent("clearTransferHistory")
    public void onClearTransferHistory(SocketIOClient client, Map<String, Object> data) {
        String sessionId = client.getSessionId().toString();
        Long userId = sessionUserMap.get(sessionId);
        
        if (userId == null) {
            Map<String, Object> errorData = new HashMap<>();
            errorData.put("message", "用户未认证");
            client.sendEvent("error", errorData);
            return;
        }

        try {
            transferRecordService.clearCompletedRecords(userId);
            Map<String, Object> successData = new HashMap<>();
            successData.put("status", "success");
            client.sendEvent("transferHistoryCleared", successData);
            logger.info("🗑️ 清除传输历史记录: userId={}", userId);
        } catch (Exception e) {
            logger.error("❌ 清除传输历史记录失败: userId={}", userId, e);
            Map<String, Object> errorData = new HashMap<>();
            errorData.put("message", "清除历史记录失败");
            client.sendEvent("error", errorData);
        }
    }

    /**
     * 处理请求活跃传输列表事件
     */
    @OnEvent("requestActiveTransfers")
    public void onRequestActiveTransfers(SocketIOClient client, Map<String, Object> data) {
        String sessionId = client.getSessionId().toString();
        Long userId = sessionUserMap.get(sessionId);

        if (userId != null) {
            logger.debug("收到同步传输状态请求: userId={}", userId);
            sendActiveTransfers(client, userId);
        }
    }

    /**
     * 发送当前进行中的传输记录
     */
    private void sendActiveTransfers(SocketIOClient client, Long userId) {
        try {
            var activeTransfers = transferRecordService.getActiveTransfers(userId);

            // 转换为DTO
            var transferDTOs = activeTransfers.stream()
                    .map(TransferRecordDTO::from)
                    .toList();

            Map<String, Object> transfersData = new HashMap<>();
            transfersData.put("transfers", transferDTOs);
            client.sendEvent("activeTransfers", transfersData);
            // logger.debug("发送进行中传输记录: userId={}, count={}", userId, activeTransfers.size()); // 开发调试用
        } catch (Exception e) {
            logger.error("❌ 发送进行中传输记录失败: userId={}", userId, e);
        }
    }

    /**
     * 向指定用户发送活跃传输列表
     */
    private void sendActiveTransfersToUser(Long userId) {
        SocketIOClient client = userClientMap.get(userId);
        if (client != null && client.isChannelOpen()) {
            sendActiveTransfers(client, userId);
        }
    }

    /**
     * 向指定用户发送传输进度更新
     * 通过Socket.IO实时推送传输进度到前端
     *
     * @param userId 用户ID
     * @param record 传输记录
     */
    public void sendTransferProgress(Long userId, TransferRecord record) {
        SocketIOClient client = userClientMap.get(userId);
        if (client != null && client.isChannelOpen()) {
            // 构建进度数据对象
            Map<String, Object> progressData = new HashMap<>();
            progressData.put("recordId", record.getId());
            progressData.put("fileName", record.getOriginalName());
            progressData.put("progress", record.getProgressPercentage());
            progressData.put("transferredBytes", record.getTransferredBytes());
            progressData.put("totalBytes", record.getFileSize());
            progressData.put("speed", record.getTransferSpeed());
            progressData.put("status", record.getTransferStatus().name());

            // 发送进度更新事件到前端
            client.sendEvent("transferProgress", progressData);
            // logger.debug("发送传输进度: userId={}, recordId={}, progress={}%",
            //            userId, record.getId(), record.getProgressPercentage()); // 开发调试用
        } else {
            // 用户Socket连接不可用时记录警告（生产环境重要信息）
            logger.warn("用户Socket连接不可用: userId={}, recordId={}", userId, record.getId());
        }
    }

    /**
     * 向指定用户发送传输完成通知
     */
    public void sendTransferCompleted(Long userId, TransferRecord record) {
        SocketIOClient client = userClientMap.get(userId);
        if (client != null && client.isChannelOpen()) {
            Map<String, Object> completedData = new HashMap<>();
            completedData.put("recordId", record.getId());
            completedData.put("transferRecordId", record.getId()); // 兼容旧版本
            completedData.put("uploadId", record.getSessionId()); // 添加uploadId用于会话匹配
            completedData.put("fileName", record.getOriginalName());
            completedData.put("status", record.getTransferStatus().name());

            // 安全处理可能为null的errorMessage
            String errorMessage = record.getErrorMessage();
            if (errorMessage != null) {
                completedData.put("errorMessage", errorMessage);
            }

            client.sendEvent("transferCompleted", completedData);
            logger.info("📤 发送传输完成通知: userId={}, recordId={}, fileName={}, status={}",
                       userId, record.getId(), record.getOriginalName(), record.getTransferStatus());
        } else {
            logger.warn("⚠️ 无法发送传输完成通知，用户未连接: userId={}", userId);
        }
    }

    /**
     * 获取在线用户数量
     */
    public int getOnlineUserCount() {
        return userClientMap.size();
    }

    /**
     * 根据用户ID获取Socket客户端
     */
    public SocketIOClient getClientByUserId(Long userId) {
        SocketIOClient client = userClientMap.get(userId);
        logger.info("🔍 查找用户客户端: userId={}, found={}", userId, client != null);
        return client;
    }

    /**
     * 根据会话ID获取用户ID
     */
    public Long getUserIdBySessionId(String sessionId) {
        Long userId = sessionUserMap.get(sessionId);
        logger.info("🔍 根据会话ID查找用户: sessionId={}, userId={}", sessionId, userId);
        return userId;
    }

    /**
     * 心跳事件处理
     */
    @OnEvent("heartbeat")
    public void onHeartbeat(SocketIOClient client, Map<String, Object> data) {
        String sessionId = client.getSessionId().toString();
        Long userId = sessionUserMap.get(sessionId);

        if (userId != null) {
            // 更新用户心跳
            userOnlineService.updateUserHeartbeat(userId);

            // 发送心跳响应
            Map<String, Object> heartbeatResponse = new HashMap<>();
            heartbeatResponse.put("status", "success");
            heartbeatResponse.put("timestamp", System.currentTimeMillis());
            heartbeatResponse.put("onlineUserCount", userOnlineService.getOnlineUserCount());
            client.sendEvent("heartbeatResponse", heartbeatResponse);
        }
    }

    /**
     * 获取在线用户列表事件
     */
    @OnEvent("getOnlineUsers")
    public void onGetOnlineUsers(SocketIOClient client, Map<String, Object> data) {
        String sessionId = client.getSessionId().toString();
        Long userId = sessionUserMap.get(sessionId);

        if (userId == null) {
            Map<String, Object> errorData = new HashMap<>();
            errorData.put("message", "用户未认证");
            client.sendEvent("error", errorData);
            return;
        }

        // 获取在线用户列表
        List<Map<String, Object>> onlineUsers = userOnlineService.getOnlineUsers();

        Map<String, Object> responseData = new HashMap<>();
        responseData.put("onlineUsers", onlineUsers);
        responseData.put("totalCount", onlineUsers.size());
        client.sendEvent("onlineUsersList", responseData);
    }

    /**
     * 获取用户状态事件
     */
    @OnEvent("getUserStatus")
    public void onGetUserStatus(SocketIOClient client, Map<String, Object> data) {
        String sessionId = client.getSessionId().toString();
        Long requestUserId = sessionUserMap.get(sessionId);

        if (requestUserId == null) {
            Map<String, Object> errorData = new HashMap<>();
            errorData.put("message", "用户未认证");
            client.sendEvent("error", errorData);
            return;
        }

        // 获取目标用户ID
        Object targetUserIdObj = data.get("userId");
        if (targetUserIdObj == null) {
            Map<String, Object> errorData = new HashMap<>();
            errorData.put("message", "缺少用户ID参数");
            client.sendEvent("error", errorData);
            return;
        }

        try {
            Long targetUserId = Long.valueOf(targetUserIdObj.toString());
            Map<String, Object> userStatus = userOnlineService.getUserStatus(targetUserId);
            userStatus.put("isOnline", userOnlineService.isUserOnline(targetUserId));

            Map<String, Object> responseData = new HashMap<>();
            responseData.put("userId", targetUserId);
            responseData.put("status", userStatus);
            client.sendEvent("userStatusResponse", responseData);

        } catch (NumberFormatException e) {
            Map<String, Object> errorData = new HashMap<>();
            errorData.put("message", "无效的用户ID");
            client.sendEvent("error", errorData);
        }
    }

    /**
     * 广播用户状态变化
     */
    private void broadcastUserStatusChange(Long userId, String status) {
        try {
            Map<String, Object> statusChangeData = new HashMap<>();
            statusChangeData.put("userId", userId);
            statusChangeData.put("status", status);
            statusChangeData.put("timestamp", System.currentTimeMillis());
            statusChangeData.put("onlineUserCount", userOnlineService.getOnlineUserCount());

            // 向所有在线用户广播状态变化
            for (SocketIOClient client : userClientMap.values()) {
                if (client.isChannelOpen()) {
                    client.sendEvent("userStatusChanged", statusChangeData);
                }
            }

            logger.debug("📡 广播用户状态变化: userId={}, status={}", userId, status);

        } catch (Exception e) {
            logger.error("❌ 广播用户状态变化失败: userId={}, status={}", userId, status, e);
        }
    }

    /**
     * 监听传输进度事件
     */
    /**
     * 处理传输进度事件
     * 当传输进度更新时，通过Socket.IO实时推送给前端
     */
    @EventListener
    public void handleTransferProgressEvent(TransferEvent.TransferProgressEvent event) {
        TransferRecord record = event.getTransferRecord();
        // logger.debug("处理传输进度事件: recordId={}, userId={}, status={}, progress={}%",
        //            record.getId(), record.getUserId(), record.getTransferStatus(), record.getProgressPercentage()); // 开发调试用

        // 立即发送进度更新到对应用户的Socket连接
        sendTransferProgress(record.getUserId(), record);

        // 同时更新活跃传输列表，确保传输列表页面数据同步
        sendActiveTransfersToUser(record.getUserId());
    }

    /**
     * 监听传输完成事件
     */
    @EventListener
    public void handleTransferCompletedEvent(TransferEvent.TransferCompletedEvent event) {
        TransferRecord record = event.getTransferRecord();
        sendTransferCompleted(record.getUserId(), record);
    }

    /**
     * 监听传输失败事件
     */
    @EventListener
    public void handleTransferFailedEvent(TransferEvent.TransferFailedEvent event) {
        TransferRecord record = event.getTransferRecord();
        sendTransferCompleted(record.getUserId(), record);
    }

    // ==================== 联系人系统相关方法 ====================

    /**
     * 更新用户在线状态到数据库
     */
    private void updateUserOnlineStatusInDB(Long userId, String sessionId, Map<String, Object> clientInfo) {
        try {
            UserOnlineStatus onlineStatus = userOnlineStatusRepository.findByUserId(userId)
                    .orElse(new UserOnlineStatus(userId));

            // 设置在线状态
            String deviceInfo = (String) clientInfo.get("userAgent");
            String ipAddress = extractIpAddress((String) clientInfo.get("remoteAddress"));

            onlineStatus.setOnline(sessionId, deviceInfo, ipAddress);
            userOnlineStatusRepository.save(onlineStatus);

            logger.debug("更新用户在线状态到数据库: userId={}, status=ONLINE", userId);
        } catch (Exception e) {
            logger.error("更新用户在线状态到数据库失败: userId={}", userId, e);
        }
    }

    /**
     * 更新用户离线状态到数据库
     */
    private void updateUserOfflineStatusInDB(Long userId) {
        try {
            UserOnlineStatus onlineStatus = userOnlineStatusRepository.findByUserId(userId)
                    .orElse(new UserOnlineStatus(userId));

            onlineStatus.setOffline();
            userOnlineStatusRepository.save(onlineStatus);

            logger.debug("更新用户离线状态到数据库: userId={}, status=OFFLINE", userId);
        } catch (Exception e) {
            logger.error("更新用户离线状态到数据库失败: userId={}", userId, e);
        }
    }

    /**
     * 通知好友用户上线
     */
    private void notifyFriendsUserOnline(Long userId) {
        try {
            // 获取用户的好友列表
            List<FriendRelationship> friendships = friendRelationshipRepository
                    .findByUserIdAndStatus(userId, FriendRelationship.Status.ACTIVE);

            // 通知每个好友
            for (FriendRelationship friendship : friendships) {
                Long friendId = friendship.getFriendId();
                SocketIOClient friendClient = userClientMap.get(friendId);

                if (friendClient != null && friendClient.isChannelOpen()) {
                    Map<String, Object> onlineNotification = new HashMap<>();
                    onlineNotification.put("type", "friend_online");
                    onlineNotification.put("userId", userId);
                    onlineNotification.put("status", "ONLINE");
                    onlineNotification.put("timestamp", System.currentTimeMillis());

                    friendClient.sendEvent("friend:status_change", onlineNotification);
                }
            }

            logger.debug("已通知好友用户上线: userId={}, friendCount={}", userId, friendships.size());
        } catch (Exception e) {
            logger.error("通知好友用户上线失败: userId={}", userId, e);
        }
    }

    /**
     * 通知好友用户下线
     */
    private void notifyFriendsUserOffline(Long userId) {
        try {
            // 获取用户的好友列表
            List<FriendRelationship> friendships = friendRelationshipRepository
                    .findByUserIdAndStatus(userId, FriendRelationship.Status.ACTIVE);

            // 通知每个好友
            for (FriendRelationship friendship : friendships) {
                Long friendId = friendship.getFriendId();
                SocketIOClient friendClient = userClientMap.get(friendId);

                if (friendClient != null && friendClient.isChannelOpen()) {
                    Map<String, Object> offlineNotification = new HashMap<>();
                    offlineNotification.put("type", "friend_offline");
                    offlineNotification.put("userId", userId);
                    offlineNotification.put("status", "OFFLINE");
                    offlineNotification.put("timestamp", System.currentTimeMillis());

                    friendClient.sendEvent("friend:status_change", offlineNotification);
                }
            }

            logger.debug("已通知好友用户下线: userId={}, friendCount={}", userId, friendships.size());
        } catch (Exception e) {
            logger.error("通知好友用户下线失败: userId={}", userId, e);
        }
    }

    /**
     * 发送好友申请通知
     */
    public void sendFriendRequestNotification(Long toUserId, FriendRequestResponse requestResponse) {
        SocketIOClient client = userClientMap.get(toUserId);
        if (client != null && client.isChannelOpen()) {
            Map<String, Object> notification = new HashMap<>();
            notification.put("type", "friend_request_received");
            notification.put("request", requestResponse);
            notification.put("timestamp", System.currentTimeMillis());

            client.sendEvent("friend:request_received", notification);
            logger.info("已发送好友申请通知: toUserId={}, fromUserId={}",
                       toUserId, requestResponse.getFromUser().getId());
        }
    }

    /**
     * 发送好友申请处理结果通知
     */
    public void sendFriendRequestResponseNotification(Long fromUserId, FriendRequestResponse requestResponse) {
        SocketIOClient client = userClientMap.get(fromUserId);
        if (client != null && client.isChannelOpen()) {
            Map<String, Object> notification = new HashMap<>();
            notification.put("type", "friend_request_" + requestResponse.getStatus().name().toLowerCase());
            notification.put("request", requestResponse);
            notification.put("timestamp", System.currentTimeMillis());

            client.sendEvent("friend:request_" + requestResponse.getStatus().name().toLowerCase(), notification);
            logger.info("已发送好友申请处理结果通知: fromUserId={}, status={}",
                       fromUserId, requestResponse.getStatus());
        }
    }

    // ==================== 联系人系统Socket.IO事件处理 ====================

    /**
     * 获取好友在线状态
     */
    @OnEvent("getFriendsOnlineStatus")
    public void onGetFriendsOnlineStatus(SocketIOClient client, Map<String, Object> data) {
        String sessionId = client.getSessionId().toString();
        Long userId = sessionUserMap.get(sessionId);

        if (userId != null) {
            try {
                // 获取好友列表
                List<FriendRelationship> friendships = friendRelationshipRepository
                        .findByUserIdAndStatus(userId, FriendRelationship.Status.ACTIVE);

                Map<String, Object> response = new HashMap<>();
                response.put("friends", friendships.stream().map(friendship -> {
                    Map<String, Object> friendInfo = new HashMap<>();
                    friendInfo.put("userId", friendship.getFriendId());
                    friendInfo.put("isOnline", userOnlineService.isUserOnline(friendship.getFriendId()));
                    return friendInfo;
                }).collect(Collectors.toList()));

                client.sendEvent("friendsOnlineStatus", response);
                logger.debug("发送好友在线状态: userId={}, friendCount={}", userId, friendships.size());
            } catch (Exception e) {
                logger.error("获取好友在线状态失败: userId={}", userId, e);
                client.sendEvent("error", Map.of("message", "获取好友在线状态失败"));
            }
        }
    }

    /**
     * 加入好友房间（为私聊做准备）
     */
    @OnEvent("joinFriendRoom")
    public void onJoinFriendRoom(SocketIOClient client, Map<String, Object> data) {
        String sessionId = client.getSessionId().toString();
        Long userId = sessionUserMap.get(sessionId);

        if (userId != null && data.containsKey("friendId")) {
            try {
                Long friendId = Long.valueOf(data.get("friendId").toString());

                // 验证好友关系
                boolean areFriends = friendRelationshipRepository
                        .existsFriendship(userId, friendId, FriendRelationship.Status.ACTIVE);

                if (areFriends) {
                    // 生成房间ID（较小的ID在前，确保唯一性）
                    String roomId = "friend_" + Math.min(userId, friendId) + "_" + Math.max(userId, friendId);
                    client.joinRoom(roomId);

                    Map<String, Object> response = new HashMap<>();
                    response.put("status", "success");
                    response.put("roomId", roomId);
                    response.put("friendId", friendId);

                    client.sendEvent("friendRoomJoined", response);
                    logger.debug("用户加入好友房间: userId={}, friendId={}, roomId={}", userId, friendId, roomId);
                } else {
                    client.sendEvent("error", Map.of("message", "非好友关系，无法加入房间"));
                }
            } catch (Exception e) {
                logger.error("加入好友房间失败: userId={}", userId, e);
                client.sendEvent("error", Map.of("message", "加入好友房间失败"));
            }
        }
    }

    /**
     * 提取IP地址
     */
    private String extractIpAddress(String remoteAddress) {
        if (remoteAddress == null) return null;

        // 处理格式如 "/127.0.0.1:12345" 的地址
        if (remoteAddress.startsWith("/")) {
            remoteAddress = remoteAddress.substring(1);
        }

        int colonIndex = remoteAddress.lastIndexOf(':');
        if (colonIndex > 0) {
            return remoteAddress.substring(0, colonIndex);
        }

        return remoteAddress;
    }
}
